<template>
  <div>
    <div class="bg-white" :class="{'shadow-light': shadow}">
      <q-markup-table class="no-shadow">
        <thead v-if="head">
        <tr>
          <th v-for="column in columns"
              :key="column.field"
              :class="getThClass(column)"
              :style="getThStyle(column)">
            <div v-if="column.ordering" class="row cursor-pointer list-link" :class="getThAlignClass(column)"
                 @click="setOrdering(column.field)">{{ column.label }}
              <q-icon v-if="ordering === column.field" name="arrow_downward" class="size-18"></q-icon>
              <q-icon v-if="ordering === '-'+column.field" name="arrow_upward" class="size-18"></q-icon>
            </div>
            <span v-else class="text-grey-7">{{ column.label }}</span>
          </th>
          <th style="width: 60px" class="text-center">
            <span class="text-grey-7">操作</span>
          </th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="instance in data" :key="instance.id">
          <td v-for="column in columns" :key="column.field" :class="getThClass(column)" :style="getThStyle(column)">
            <template v-if="!$scopedSlots[column.field]">
              <div v-if="!column.format">
                <span v-if="!column.link">{{ getTdLabel(column, instance) }}</span>
                <a v-else class="text-grey-9 size-16 list-link" :href="column.link.url(instance)"
                   :target="column.link.target || '_self'">{{ getTdLabel(column, instance) }}</a>
              </div>
              <div v-else-if="column.format === 'head'" class="row">
                <a-head v-if="!column.link" :user="instance[column.field]" :size="24"></a-head>
                <a v-else class="row items-center list-link text-grey-9" :href="column.link.url(instance)"
                   :target="column.link.target || '_self'">
                  <a-head :user="instance[column.field]" :size="24" :popover="false" :username="false"
                          class="q-mr-xs"></a-head>
                  <span class="size-16">{{ instance[column.field].username }}</span>
                </a>
              </div>
              <div v-else-if="column.format === 'boolean'" class="row justify-center size-16 row items-center">
                <q-icon v-if="instance[column.field]" name="done" color="positive"/>
                <q-icon v-else name="not_interested" color="grey"/>
              </div>
              <span v-else-if="column.format === 'date'">
                {{ instance[column.field].slice(0, 10) }}
            </span>
              <span v-else-if="column.format === 'timesince'">
                {{ timesince(instance[column.field]) }}
            </span>
              <q-chip v-else-if="column.format === 'fileformat'" dense color="primary" class="uppercase">
                {{ instance[column.field] }}
              </q-chip>
              <span v-else-if="column.format === 'filesize'">
                {{ fileSizeFormat(instance[column.field] ) }}
            </span>
            </template>
            <slot :name="column.field" :instance="instance"></slot>
          </td>
          <td class="text-center th-mini">
            <slot name="action" :instance="instance"></slot>
          </td>
        </tr>
        </tbody>
      </q-markup-table>
      <a-loading :visible="loading"></a-loading>
      <a-none v-if="!data || data.length === 0"></a-none>
    </div>
    <a-pagination :page="page" :max="max" v-if="data && max > 1" @input="$emit('page', $event)"
                  :changeRoute="changeRoute"></a-pagination>
  </div>
</template>

<script>
  export default {
    name: 'aTable',
    props: {
      data: {
        type: Array,
        required: true
      },
      columns: {
        type: Array,
        required: true
      },
      page: {
        type: [Number, String],
        required: true
      },
      max: {
        type: Number,
        required: true
      },
      ordering: {
        type: String,
        required: false,
        default: ''
      },
      loading: {
        type: Boolean,
        required: false,
        default: false
      },
      head: {
        type: Boolean,
        required: false,
        default: true
      },
      shadow: {
        type: Boolean,
        required: false,
        default: true
      },
      changeRoute: {
        type: Boolean,
        required: false,
        default: true
      }
    },
    data () {
      return {
        textCenterFormat: ['boolean', 'date', 'timesince', 'fileformat', 'filesize']
      }
    },
    computed: {
      orderingField () {
        if (!this.ordering) {
          return ''
        }

        if (this.ordering && this.ordering.match(/^-/)) {
          this.ordering.replace('-', '')
        } else {
          return this.ordering
        }

        return null
      }
    },
    watch: {},
    methods: {
      getTdLabel (column, instance) {
        if (column.content) {
          return column.content(instance)
        }

        return instance[column.field]
      },
      getThClass (column) {
        let thClass = 'text-left'

        if (column.align) {
          const align = column.align
          thClass = `text-${align}`
        }

        return column.class ? column.class + ' ' + thClass : thClass
      },
      getThAlignClass (column) {
        if (column.align === 'left') {
          return 'justify-start'
        }
        if (column.align === 'center') {
          return 'justify-center'
        }
        if (column.align === 'right') {
          return 'justify-end'
        }

        return 'justify-start'
      },
      getThStyle (column) {
        const thStyle = {}

        if (column.width) {
          thStyle.width = column.width
        }

        if (column.style) {
          Object.assign(thStyle, column.style)
        }

        return thStyle
      },
      setOrdering (ordering) {
        if (ordering === this.orderingField) {
          if (!this.ordering.match(/^-/)) {
            ordering = `-${ordering}`
          }
        }

        if (this.changeRoute) {
          this.$router.push(this.getRoute({ query: { ordering } }))
        }
        this.$emit('ordering', ordering)
      },
      fileSizeFormat (size) {
        if (size < 1024) {
          return '1KB'
        } else if (size < 1024 * 1024) {
          return ((size / 1024)).toFixed(0) + 'KB'
        } else if (size < 1024 * 1024 * 1024) {
          return ((size / 1024 / 1014)).toFixed(1) + 'MB'
        }
      }
    }
  }
</script>

<style lang="stylus">
  .q-table
    .th-mini
      width 60px
    .q-input-target
      font-size 14px !important
</style>
